package com.xcity.game.battle.res;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xcity.db.entity.Employee;
import com.xcity.db.entity.Player;
import com.xcity.game.battle.pve.PVEStageDropListener;
import com.xcity.game.battle.pve.PVEUtils;
import com.xcity.game.battle.pve.template.ResStageTemplate;
import com.xcity.game.battle.pve.template.ResStageTypeTemplate;
import com.xcity.game.common.Cause;
import com.xcity.game.common.GameStaticConfig;
import com.xcity.game.common.MessageConst;
import com.xcity.game.event.GameEvents;
import com.xcity.game.formation.Formation;
import com.xcity.game.formation.FormationManager;
import com.xcity.game.item.drop.Drop;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.request.ResStageDifficultyListRequest;
import com.xcity.pomelo.request.ResStageSweepRequest;
import com.xcity.pomelo.request.ResStageTypeListRequest;
import com.xcity.pomelo.response.HintResponse;
import com.xcity.pomelo.response.ResStageDifficultyListResponse;
import com.xcity.pomelo.response.ResStageSweepResponse;
import com.xcity.pomelo.response.ResStageTypeListResponse;

import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.Service;
import naga.x.service.ServiceException;

/**
 * 资源副本
 */
@OPHandler
public class ResStageService implements Service, EventListener{

	protected List<ResStageTemplate> templates;
	protected List<ResStageTypeTemplate> typeTempList;
	protected static final Logger LOG = LoggerFactory.getLogger(ResStageService.class);
	@Override
	public int[] getEventTypes() {
		return new int[]{GameEvents.EVENT_PLAYER_LOGIN,
				};
	}

	@Override
	public void handleEvent(Event event) {
		switch (event.getType()) {
		case GameEvents.EVENT_PLAYER_LOGIN:
			playerLogin(event.getParameter());
			break;
		}
	}

	@Override
	public void startup() throws ServiceException {
		TemplateService service = App.getApp().getServiceManager().get(TemplateService.class);
		templates = service.getTemplatesList(ResStageTemplate.class);
		typeTempList = service.getTemplatesList(ResStageTypeTemplate.class);
		int size = typeTempList.size();
		int lastType = 0;
		int lastIndex = -1;
		for(int i = 0; i < templates.size(); i++){
			ResStageTemplate temp = templates.get(i);
			if(lastIndex > -1){
				if(lastType == temp.getType()){
					temp.setPreviousIndex(lastIndex);
				}
			}
			lastIndex = i;
			lastType = temp.getType();
			if(lastType < 0 || lastType >= size){
				System.out.println("resstage.xlsx配置类型有错 id=" + temp.getId());
				throw new ServiceException();
			}
		}
		App.getApp().getEventManager().register(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public String getId() {
		return getClass().getName();
	}

	public List<ResStageTypeTemplate> getTypeTempList() {
		return typeTempList;
	}

	private void playerLogin(Player player){
		List<ResStage> stages = player.getResStages().getStages();
		if(stages.size() != templates.size()){
			player.getResStages().initStages(templates);
		}
		if(typeTempList.size() != player.getResStages().getTypeInfo().getType2dayFightCount().size()){
			player.getResStages().initTypeInfo(typeTempList);
		}
	}
	
	@PomeloOP(PomeloRoute.RESSTAGE_TYPE_LIST)
	public void requestResStageList(Session session, ResStageTypeListRequest req){
		Player player = session.getClient();
		if(player.getLevel() < GameStaticConfig.resStageOpenLvl){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NOT_OPEN));
			return;
		}
		player.send(new ResStageTypeListResponse(req.getSerial(), player, typeTempList));
	}
	
	@PomeloOP(PomeloRoute.RESSTAGE_DIFFICULTY_LIST)
	public void requestResStageDifficultyList(Session session, ResStageDifficultyListRequest req){
		Player player = session.getClient();
		int type = req.getType();
		if(!player.getResStages().checkType(type)){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_STAGE));
			return;
		}
		//等级
		if(player.getLevel() < GameStaticConfig.resStageOpenLvl){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NOT_OPEN));
			return;
		}
		ResStageTypeTemplate typeTemp = typeTempList.get(type);
		if(typeTemp == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_STAGE));
			return;
		}
		if(player.getLevel() < typeTemp.getLevelLimit()){
			player.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.RES_STAGE_LEVEL_LIMIT, typeTemp.getLevelLimit())));
			return;
		}
		List<ResStage> stageList = player.getResStages().getStagesByType(type);
		if(stageList == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_STAGE));
			return;
		}
		player.send(new ResStageDifficultyListResponse(req.getSerial(), type, stageList));
	}
	
	@PomeloOP(PomeloRoute.RESSTAGE_SWEEP)
	public void requestResStageSweep(Session session, ResStageSweepRequest req){
		Player player = session.getClient();
		int index = req.getId();
		ResStage stage = player.getResStages().getStageByIndex(index);
		if(stage == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_STAGE));
			return;
		}
		int type = stage.getTemplate().getType();
		if(!player.getResStages().checkType(type)){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_STAGE));
			return;
		}
		//等级
		if(player.getLevel() < GameStaticConfig.resStageOpenLvl){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NOT_OPEN));
			return;
		}
		ResStageTypeTemplate typeTemp = typeTempList.get(type);
		if(typeTemp == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_STAGE));
			return;
		}
		int limit = typeTemp.getLevelLimit();
		if(limit > stage.getTemplate().getLevelLimit()){
			limit = stage.getTemplate().getLevelLimit();
		}
		if(player.getLevel() < limit){
			player.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.RES_STAGE_LEVEL_LIMIT, limit)));
			return;
		}
		//次数
		if(player.getResStages().getTodayCount(stage) >= player.getResStages().getTodayMaxCount(stage)){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NO_COUNT));
			return;
		}
		//TODO 副本体力-
		int cost = App.getApp().getServiceManager().get(ResStageService.class).getTypeTempList().get(type).getCost();
		if(player.getVigour() < cost){
			player.send(new HintResponse(req.getSerial(), MessageConst.VIGOUR_NOT_ENOUGH));
			return;
		}
		//CD
		if(player.getResStages().getTypeInfo().getLeftSecondByType(type) > 0){
			player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NOT_TIMEUP));
			return;
		}
		//previous
		if(stage.getTemplate().getPreviousIndex() > 0){
			ResStage resStage = player.getResStages().getStageByIndex(stage.getTemplate().getPreviousIndex());
			if(resStage != null){
				if(!resStage.isPass()){
					player.send(new HintResponse(req.getSerial(), MessageConst.RES_STAGE_NEED_PREVIOUS_PASS));
					return;
				}
			}
		}
		List<Drop> allDrops = stage.getTemplate().getRewardsDrop();
		List<Drop> resultDropList = new ArrayList<Drop>();
		List<PVEStageDropListener> listenerList = new ArrayList<PVEStageDropListener>();
		
//		long[] employeeIds = CombatUtils.getCombatFormation(player, true);
//		List<Employee> employees = new ArrayList<Employee>(employeeIds.length);
//		for(long eid : employeeIds){
//			Employee e = eid != 0L? player.getEmployees().get(eid) : null;
//			employees.add(e);
//		}
		List<Employee> employees = Collections.emptyList();
		Formation f = player.getFormations().get(Formation.TYPE_NORMAL);
		if (f != null) {
			employees = Arrays.asList(f.getUnits());
		}
		PVEUtils.calcPVEStageDrop(player, employees, stage.getTemplate().getNpcs(), stage.getTemplate().getBoss(), resultDropList, allDrops, 0, 1, listenerList, Cause.RES_STAGE_SWEEP);
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_RES_SUCCESS, player);
		//TODO 副本体力-
		player.decVigour(cost, Cause.RES_STAGE_SWEEP);
		//次数
		player.getResStages().getTypeInfo().tryAddDayCount(type);
		//CD
		player.getResStages().getTypeInfo().setLastFightTime(type, TimeUpdater.getInstance().now());
		player.send(new ResStageSweepResponse(req.getSerial(), player, stage, listenerList.get(0).getMoney(), listenerList.get(0).getExp(), listenerList.get(0).getItems()));
	}
}
